<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>缓存管理 - 币安K线分析系统</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
    <style>
        .cache-card {
            margin-bottom: 20px;
            transition: all 0.3s;
        }
        .cache-card:hover {
            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
        }
        .loading {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(255,255,255,0.8);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 9999;
        }
        .badge-age-fresh {
            background-color: #28a745;
        }
        .badge-age-normal {
            background-color: #17a2b8;
        }
        .badge-age-old {
            background-color: #ffc107;
        }
        .badge-age-expired {
            background-color: #dc3545;
        }
    </style>
</head>
<body>
    <div class="loading" id="loading">
        <div class="spinner-border text-primary" role="status">
            <span class="visually-hidden">加载中...</span>
        </div>
    </div>

    <div class="container mt-4">
        <div class="row">
            <div class="col-12">
                <div class="d-flex justify-content-between align-items-center mb-4">
                    <h1>缓存管理</h1>
                    <div>
                        <button class="btn btn-primary me-2" id="refreshAll">刷新所有缓存</button>
                        <button class="btn btn-danger" id="clearAll">清空所有缓存</button>
                    </div>
                </div>
            </div>
        </div>

        <div class="row mb-4">
            <div class="col-md-6">
                <div class="card">
                    <div class="card-header">
                        <h5 class="card-title mb-0">缓存概览</h5>
                    </div>
                    <div class="card-body">
                        <div id="cacheOverview">
                            <div class="placeholder-glow">
                                <p class="placeholder col-12"></p>
                                <p class="placeholder col-12"></p>
                                <p class="placeholder col-12"></p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-md-6">
                <div class="card">
                    <div class="card-header">
                        <h5 class="card-title mb-0">缓存统计</h5>
                    </div>
                    <div class="card-body">
                        <div id="cacheStats">
                            <div class="placeholder-glow">
                                <p class="placeholder col-12"></p>
                                <p class="placeholder col-12"></p>
                                <p class="placeholder col-12"></p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <div class="row mb-4">
            <div class="col-12">
                <div class="card">
                    <div class="card-header d-flex justify-content-between align-items-center">
                        <h5 class="card-title mb-0">缓存管理</h5>
                        <div class="d-flex">
                            <input type="text" class="form-control me-2" id="searchCache" placeholder="搜索缓存..." style="width: 200px;">
                            <div class="input-group" style="width: 400px;">
                                <select class="form-select" id="symbolFilter">
                                    <option value="">全部交易对</option>
                                    <option value="BTCUSDT">BTCUSDT</option>
                                    <option value="ETHUSDT">ETHUSDT</option>
                                </select>
                                <select class="form-select" id="intervalFilter">
                                    <option value="">全部时间间隔</option>
                                    <option value="1d">1d</option>
                                    <option value="1h">1h</option>
                                    <option value="30m">30m</option>
                                    <option value="15m">15m</option>
                                    <option value="10m">10m</option>
                                    <option value="5m">5m</option>
                                </select>
                                <select class="form-select" id="rangeFilter">
                                    <option value="">全部时间范围</option>
                                    <option value="today">今天</option>
                                    <option value="yesterday">昨天</option>
                                    <option value="1w">1周</option>
                                    <option value="1m">1个月</option>
                                    <option value="3m">3个月</option>
                                    <option value="6m">6个月</option>
                                    <option value="1y">1年</option>
                                    <option value="2y">2年</option>
                                </select>
                            </div>
                        </div>
                    </div>
                    <div class="card-body">
                        <div class="row" id="cacheList">
                            <div class="col-12 text-center">
                                <div class="placeholder-glow">
                                    <div class="placeholder col-12 mb-3" style="height: 100px;"></div>
                                    <div class="placeholder col-12 mb-3" style="height: 100px;"></div>
                                    <div class="placeholder col-12 mb-3" style="height: 100px;"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 登录模态框 -->
    <div class="modal fade" id="loginModal" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">管理员登录</h5>
                </div>
                <div class="modal-body">
                    <form id="loginForm">
                        <div class="mb-3">
                            <label for="username" class="form-label">用户名</label>
                            <input type="text" class="form-control" id="username" required>
                        </div>
                        <div class="mb-3">
                            <label for="password" class="form-label">密码</label>
                            <input type="password" class="form-control" id="password" required>
                        </div>
                        <div class="alert alert-danger d-none" id="loginError"></div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary" id="loginButton">登录</button>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // 身份认证
        let authToken = '';
        const loginModal = new bootstrap.Modal(document.getElementById('loginModal'));

        // 页面加载完成后显示登录模态框
        document.addEventListener('DOMContentLoaded', () => {
            loginModal.show();
        });

        // 登录按钮点击事件
        document.getElementById('loginButton').addEventListener('click', async () => {
            const username = document.getElementById('username').value;
            const password = document.getElementById('password').value;
            
            if (!username || !password) {
                showLoginError('请输入用户名和密码');
                return;
            }

            try {
                // 生成Basic Auth token
                authToken = btoa(`${username}:${password}`);
                
                // 测试认证
                const response = await fetch('/api/admin/cache/stats', {
                    headers: {
                        'Authorization': `Basic ${authToken}`
                    }
                });
                
                if (response.ok) {
                    // 登录成功，关闭模态框
                    loginModal.hide();
                    // 加载数据
                    loadCacheData();
                } else if (response.status === 401 || response.status === 403) {
                    showLoginError('用户名或密码错误');
                } else {
                    showLoginError('服务器错误，请稍后重试');
                }
            } catch (error) {
                showLoginError('请求失败，请检查网络连接');
                console.error('登录失败:', error);
            }
        });

        // 显示登录错误信息
        function showLoginError(message) {
            const errorElement = document.getElementById('loginError');
            errorElement.textContent = message;
            errorElement.classList.remove('d-none');
        }

        // 加载缓存数据
        async function loadCacheData() {
            showLoading();
            try {
                // 获取缓存统计
                const statsResponse = await fetch('/api/admin/cache/stats', {
                    headers: {
                        'Authorization': `Basic ${authToken}`
                    }
                });
                
                if (!statsResponse.ok) {
                    throw new Error('获取缓存统计失败');
                }
                
                const statsData = await statsResponse.json();
                
                // 显示缓存概览
                const overview = statsData.data.summary;
                const overviewHtml = `
                    <div class="row">
                        <div class="col-md-6">
                            <p><strong>缓存总数:</strong> ${overview.total_cache}</p>
                            <p><strong>交易对数量:</strong> ${overview.unique_symbols}</p>
                            <p><strong>时间周期数量:</strong> ${overview.unique_intervals}</p>
                        </div>
                        <div class="col-md-6">
                            <p><strong>时间范围数量:</strong> ${overview.unique_ranges}</p>
                            <p><strong>最早缓存:</strong> ${new Date(overview.oldest_cache).toLocaleString()}</p>
                            <p><strong>最新缓存:</strong> ${new Date(overview.newest_cache).toLocaleString()}</p>
                            <p><strong>平均缓存年龄:</strong> ${Math.round(overview.avg_age_minutes)} 分钟</p>
                        </div>
                    </div>
                `;
                document.getElementById('cacheOverview').innerHTML = overviewHtml;

                // 显示缓存统计
                const rangeStats = statsData.data.rangeStats;
                let rangeStatsHtml = '<div class="row">';
                
                rangeStats.forEach(stat => {
                    rangeStatsHtml += `
                        <div class="col-md-3 mb-2">
                            <div class="card">
                                <div class="card-body p-2 text-center">
                                    <h5>${stat.range}</h5>
                                    <p class="mb-0">${stat.count} 个缓存</p>
                                </div>
                            </div>
                        </div>
                    `;
                });
                
                rangeStatsHtml += '</div>';
                document.getElementById('cacheStats').innerHTML = rangeStatsHtml;

                // 获取缓存列表
                await loadCacheList();
            } catch (error) {
                console.error('加载缓存数据失败:', error);
                alert('加载缓存数据失败: ' + error.message);
            } finally {
                hideLoading();
            }
        }

        // 加载缓存列表
        async function loadCacheList() {
            const symbolFilter = document.getElementById('symbolFilter').value;
            const intervalFilter = document.getElementById('intervalFilter').value;
            const rangeFilter = document.getElementById('rangeFilter').value;
            const searchQuery = document.getElementById('searchCache').value.toLowerCase();

            try {
                // 构建查询参数
                const queryParams = new URLSearchParams();
                if (symbolFilter) queryParams.append('symbol', symbolFilter);
                if (intervalFilter) queryParams.append('interval', intervalFilter);
                if (rangeFilter) queryParams.append('range', rangeFilter);
                
                const response = await fetch(`/api/admin/cache/stats`, {
                    headers: {
                        'Authorization': `Basic ${authToken}`
                    }
                });
                
                if (!response.ok) {
                    throw new Error('获取缓存列表失败');
                }
                
                const data = await response.json();
                const stats = data.data.summary;
                
                // 获取所有缓存记录
                const allCaches = await getAllCaches();
                
                // 过滤缓存记录
                const filteredCaches = allCaches.filter(cache => {
                    const matchSymbol = !symbolFilter || cache.symbol === symbolFilter;
                    const matchInterval = !intervalFilter || cache.interval === intervalFilter;
                    const matchRange = !rangeFilter || cache.range === rangeFilter;
                    const matchSearch = !searchQuery || 
                        cache.symbol.toLowerCase().includes(searchQuery) || 
                        cache.interval.toLowerCase().includes(searchQuery) || 
                        cache.range.toLowerCase().includes(searchQuery);
                    
                    return matchSymbol && matchInterval && matchRange && matchSearch;
                });
                
                // 渲染缓存列表
                if (filteredCaches.length === 0) {
                    document.getElementById('cacheList').innerHTML = `
                        <div class="col-12 text-center">
                            <p class="text-muted">未找到符合条件的缓存</p>
                        </div>
                    `;
                    return;
                }
                
                let cacheListHtml = '';
                
                filteredCaches.forEach(cache => {
                    const ageInMinutes = (new Date() - new Date(cache.updated_at)) / (1000 * 60);
                    let ageBadgeClass = 'badge-age-fresh';
                    let ageText = '新鲜';
                    
                    if (ageInMinutes < 30) {
                        ageBadgeClass = 'badge-age-fresh';
                        ageText = '新鲜';
                    } else if (ageInMinutes < 120) {
                        ageBadgeClass = 'badge-age-normal';
                        ageText = '正常';
                    } else if (ageInMinutes < 1440) { // 24小时
                        ageBadgeClass = 'badge-age-old';
                        ageText = '较旧';
                    } else {
                        ageBadgeClass = 'badge-age-expired';
                        ageText = '过期';
                    }
                    
                    cacheListHtml += `
                        <div class="col-md-4">
                            <div class="card cache-card">
                                <div class="card-header d-flex justify-content-between align-items-center">
                                    <h5 class="card-title mb-0">${cache.symbol} - ${cache.interval} - ${cache.range}</h5>
                                    <span class="badge ${ageBadgeClass}">${ageText}</span>
                                </div>
                                <div class="card-body">
                                    <p><strong>总K线数:</strong> ${cache.total}</p>
                                    <p><strong>上涨:</strong> ${cache.up} (${(cache.up / cache.total * 100).toFixed(2)}%)</p>
                                    <p><strong>下跌:</strong> ${cache.down} (${(cache.down / cache.total * 100).toFixed(2)}%)</p>
                                    <p><strong>更新时间:</strong> ${new Date(cache.updated_at).toLocaleString()}</p>
                                </div>
                                <div class="card-footer d-flex justify-content-between">
                                    <button class="btn btn-sm btn-primary refresh-cache" data-symbol="${cache.symbol}" data-interval="${cache.interval}" data-range="${cache.range}">刷新</button>
                                    <button class="btn btn-sm btn-danger clear-cache" data-symbol="${cache.symbol}" data-interval="${cache.interval}" data-range="${cache.range}">清除</button>
                                </div>
                            </div>
                        </div>
                    `;
                });
                
                document.getElementById('cacheList').innerHTML = cacheListHtml;
                
                // 绑定事件
                document.querySelectorAll('.refresh-cache').forEach(button => {
                    button.addEventListener('click', refreshCache);
                });
                
                document.querySelectorAll('.clear-cache').forEach(button => {
                    button.addEventListener('click', clearCache);
                });
            } catch (error) {
                console.error('加载缓存列表失败:', error);
                document.getElementById('cacheList').innerHTML = `
                    <div class="col-12 text-center">
                        <p class="text-danger">加载缓存列表失败: ${error.message}</p>
                    </div>
                `;
            }
        }

        // 获取所有缓存
        async function getAllCaches() {
            // 由于没有直接获取所有缓存的API，我们通过列出所有支持的交易对和时间间隔组合来尝试获取缓存数据
            const symbols = ['BTCUSDT', 'ETHUSDT'];
            const intervals = ['1d', '1h', '30m', '15m', '10m', '5m'];
            const ranges = ['today', 'yesterday', '1w', '1m', '3m', '6m', '1y', '2y'];
            
            const results = [];
            
            for (const symbol of symbols) {
                for (const interval of intervals) {
                    for (const range of ranges) {
                        try {
                            const response = await fetch(`/api/admin/cache?symbol=${symbol}&interval=${interval}&range=${range}`, {
                                headers: {
                                    'Authorization': `Basic ${authToken}`
                                }
                            });
                            
                            if (response.ok) {
                                const data = await response.json();
                                
                                // 获取缓存更新时间
                                const dbResponse = await fetch(`/api/admin/cache/stats`, {
                                    headers: {
                                        'Authorization': `Basic ${authToken}`
                                    }
                                });
                                
                                if (dbResponse.ok) {
                                    const dbData = await dbResponse.json();
                                    const updated_at = new Date().toISOString(); // 默认为当前时间
                                    
                                    results.push({
                                        symbol,
                                        interval,
                                        range,
                                        total: data.data.total,
                                        up: data.data.up,
                                        down: data.data.down,
                                        updated_at
                                    });
                                }
                            }
                        } catch (error) {
                            console.error(`获取缓存 ${symbol}-${interval}-${range} 失败:`, error);
                        }
                    }
                }
            }
            
            return results;
        }

        // 刷新缓存
        async function refreshCache(event) {
            const symbol = event.target.dataset.symbol;
            const interval = event.target.dataset.interval;
            const range = event.target.dataset.range;
            
            showLoading();
            try {
                const response = await fetch('/api/admin/cache/refresh', {
                    method: 'POST',
                    headers: {
                        'Authorization': `Basic ${authToken}`,
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ symbol, interval, range })
                });
                
                if (!response.ok) {
                    throw new Error('刷新缓存失败');
                }
                
                // 重新加载数据
                await loadCacheData();
                alert(`成功刷新缓存: ${symbol}-${interval}-${range}`);
            } catch (error) {
                console.error('刷新缓存失败:', error);
                alert('刷新缓存失败: ' + error.message);
            } finally {
                hideLoading();
            }
        }

        // 清除缓存
        async function clearCache(event) {
            const symbol = event.target.dataset.symbol;
            const interval = event.target.dataset.interval;
            const range = event.target.dataset.range;
            
            if (!confirm(`确定要清除 ${symbol}-${interval}-${range} 的缓存吗？`)) {
                return;
            }
            
            showLoading();
            try {
                const response = await fetch(`/api/admin/cache?symbol=${symbol}&interval=${interval}&range=${range}`, {
                    method: 'DELETE',
                    headers: {
                        'Authorization': `Basic ${authToken}`
                    }
                });
                
                if (!response.ok) {
                    throw new Error('清除缓存失败');
                }
                
                // 重新加载数据
                await loadCacheData();
                alert(`成功清除缓存: ${symbol}-${interval}-${range}`);
            } catch (error) {
                console.error('清除缓存失败:', error);
                alert('清除缓存失败: ' + error.message);
            } finally {
                hideLoading();
            }
        }

        // 刷新所有缓存
        document.getElementById('refreshAll').addEventListener('click', async () => {
            if (!confirm('确定要刷新所有缓存吗？这可能需要较长时间。')) {
                return;
            }
            
            showLoading();
            try {
                const response = await fetch('/api/admin/cache/refresh-all', {
                    method: 'POST',
                    headers: {
                        'Authorization': `Basic ${authToken}`
                    }
                });
                
                if (!response.ok) {
                    throw new Error('刷新所有缓存失败');
                }
                
                // 获取响应数据
                const data = await response.json();
                
                // 显示成功消息
                alert(`缓存更新任务已启动，请稍后查看结果。\n启动时间: ${data.data.startTime}`);
                
                // 3秒后重新加载数据
                setTimeout(async () => {
                    await loadCacheData();
                }, 3000);
            } catch (error) {
                console.error('刷新所有缓存失败:', error);
                alert('刷新所有缓存失败: ' + error.message);
            } finally {
                hideLoading();
            }
        });

        // 清空所有缓存
        document.getElementById('clearAll').addEventListener('click', async () => {
            if (!confirm('确定要清空所有缓存吗？此操作不可恢复！')) {
                return;
            }
            
            showLoading();
            try {
                const response = await fetch('/api/admin/cache', {
                    method: 'DELETE',
                    headers: {
                        'Authorization': `Basic ${authToken}`
                    }
                });
                
                if (!response.ok) {
                    throw new Error('清空所有缓存失败');
                }
                
                // 重新加载数据
                await loadCacheData();
                alert('成功清空所有缓存');
            } catch (error) {
                console.error('清空所有缓存失败:', error);
                alert('清空所有缓存失败: ' + error.message);
            } finally {
                hideLoading();
            }
        });

        // 搜索和筛选事件
        document.getElementById('searchCache').addEventListener('input', loadCacheList);
        document.getElementById('symbolFilter').addEventListener('change', loadCacheList);
        document.getElementById('intervalFilter').addEventListener('change', loadCacheList);
        document.getElementById('rangeFilter').addEventListener('change', loadCacheList);

        // 显示/隐藏加载中
        function showLoading() {
            document.getElementById('loading').style.display = 'flex';
        }

        function hideLoading() {
            document.getElementById('loading').style.display = 'none';
        }
    </script>
</body>
</html> 